
#include <QStackedLayout>
#include <QState>
#include <QStateMachine>

#include "core/engine.h"
#include "core/game.h"
#include "core/scene.h"
#include "ui/home.h"
#include "ui/hud.h"
#include "ui/lobby.h"
#include "ui/score.h"
#include "ui/ui.h"

Ui::Ui(QWidget* pkParent)
    : QWidget(pkParent),
      m_pkHome(new Home(this)),
      m_pkHud(new Hud(this)),
      m_pkLobby(new Lobby(this)),
      m_pkScore(new Score(this))
{
    Q_CHECK_PTR(m_pkHome);
    Q_CHECK_PTR(m_pkLobby);
    Q_CHECK_PTR(m_pkHud);
    Q_CHECK_PTR(m_pkScore);

    setAutoFillBackground(false);
    setWindowFlags(Qt::FramelessWindowHint);
    setAttribute(Qt::WA_TranslucentBackground);

    // Widget layout setup.
    setLayout(new QStackedLayout);
    layout()->addWidget(m_pkHome);
    layout()->addWidget(m_pkLobby);
    layout()->addWidget(m_pkHud);
    layout()->addWidget(m_pkScore);

    // State machine setup.
    QStateMachine* pkStateMachine = new QStateMachine(this);

    QState* pkHomeState = new QState();
    pkHomeState->assignProperty(layout(), "currentIndex", layout()->indexOf(m_pkHome));
    pkStateMachine->addState(pkHomeState);

    QState* pkLobbyState = new QState();
    pkLobbyState->assignProperty(layout(), "currentIndex", layout()->indexOf(m_pkLobby));
    pkStateMachine->addState(pkLobbyState);

    QState* pkPlayState = new QState();
    pkPlayState->assignProperty(layout(), "currentIndex", layout()->indexOf(m_pkHud));
    pkStateMachine->addState(pkPlayState);

    QState* pkScoreState = new QState();
    pkScoreState->assignProperty(layout(), "currentIndex", layout()->indexOf(m_pkScore));
    pkStateMachine->addState(pkScoreState);

    // Transitions setup.
    pkHomeState->addTransition(m_pkHome, SIGNAL(start()), pkLobbyState);
    pkLobbyState->addTransition(m_pkLobby, SIGNAL(start()), pkPlayState);
    pkPlayState->addTransition(&(Engine::instance().game()), SIGNAL(gameOver()), pkScoreState);
    pkScoreState->addTransition(m_pkScore, SIGNAL(home()), pkHomeState);

    // Connections setup.
    connect(m_pkLobby, SIGNAL(difficultySelected(int)), &(Engine::instance().game()), SLOT(setDifficulty(int)));
    connect(m_pkLobby, SIGNAL(start()), &(Engine::instance().game()), SLOT(start()));
    connect(m_pkScore, SIGNAL(home()), &(Engine::instance().game()), SLOT(clear()));

    // Initialize & start.
    pkStateMachine->setInitialState(pkHomeState);
    pkStateMachine->start();
}

Ui::~Ui()
{
}
